package com.sum.slike;

import java.util.ArrayList;
import java.util.List;

/**
 * @author: zhu_zhonglin
 * @time: 2021/4/26
 */
public class AnimationFramePool {

    private static final int DURATION = 1000;
    private final List<AnimationFrame> runningFrameList;
    private final List<AnimationFrame> idleFrameList;


    private final int maxFrameSize;
    private final int elementAmount;
    private int frameCount;

    /**
     *
     * @param maxFrameSize maxFrameSize
     * @param elementAmount elementAmount
     */
    public AnimationFramePool(final int maxFrameSize, final int elementAmount) {
        this.maxFrameSize = maxFrameSize;
        this.elementAmount = elementAmount;
        runningFrameList = new ArrayList<>(maxFrameSize);
        idleFrameList = new ArrayList<>(maxFrameSize);
    }

    /**
     * hasRunningAnimation
     * @return hasRunningAnimation
     */
    public boolean hasRunningAnimation() {
        return runningFrameList.size() > 0;
    }

    /**
     * 绑定
     * @param type type
     * @return AnimationFrame
     */
    public AnimationFrame obtain(final int type) {

        // RunningAnimationFrame 存在onlyOne直接复用
        AnimationFrame animationFrame = getRunningFrameListByOnlyOneAndType(type);
        if (animationFrame != null) {
            return animationFrame;
        }

        // 有空闲AnimationFrame直接使用, 加入runningFrame队列中
        animationFrame = removeIdleFrameListDownByType(type);
        if (animationFrame == null && frameCount < maxFrameSize) {
            frameCount++;
            if (type == EruptionAnimationFrame.TYPE) {
                animationFrame = new EruptionAnimationFrame(elementAmount, DURATION);
            } else {
                animationFrame = new TextAnimationFrame(DURATION);
            }
        }
        if (animationFrame != null) {
            runningFrameList.add(animationFrame);
        }

        return animationFrame;
    }

    private AnimationFrame getRunningFrameListByOnlyOneAndType(final int type) {
        for (int i = runningFrameList.size() - 1; i >= 0; i--) {
            AnimationFrame animationFrame = runningFrameList.get(i);
            if (type == animationFrame.getType() && animationFrame.onlyOne()) {
                return animationFrame;
            }
        }
        return null;
    }

    void recycleAll() {
        for (int i = runningFrameList.size() - 1; i >= 0; i--) {
            AnimationFrame animationFrame = runningFrameList.get(i);
            recycle(animationFrame);
            animationFrame.reset();
        }
    }

    void recycle(final AnimationFrame animationFrame) {
        runningFrameList.remove(animationFrame);
        idleFrameList.add(animationFrame);
    }

    /**
     * getRunningFrameList
     * @return AnimationFrame集合列表
     */
    public List<AnimationFrame> getRunningFrameList() {
        return runningFrameList;
    }

    /**
     * getIdleFrameList
     * @return AnimationFrame集合列表
     */
    public List<AnimationFrame> getIdleFrameList() {
        return idleFrameList;
    }

    private AnimationFrame removeIdleFrameListDownByType(final int type) {
        for (int i = idleFrameList.size() - 1; i >= 0; i--) {
            AnimationFrame animationFrame = idleFrameList.get(i);
            if (type == animationFrame.getType()) {
                return idleFrameList.remove(i);
            }
        }
        return null;
    }
}
